home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Graphics / STIMP_noise / source / ppmcolmedian / ppmcolmedian.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  5.4 KB  |  236 lines

  1.  
  2. /************************************************************************/
  3. #define OP_NAME      "ppmcolmedian"
  4. #define VERSION      "1.02"
  5. #define DATE         "31.01.98"
  6. #define AUTHOR       "Stefan Diener"
  7. /************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdarg.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>
  14. #include <sys/types.h>
  15.  
  16. #include <STIMP/ppm.c>
  17.  
  18. struct PPM_Info source, desti;
  19. static int m, n;
  20. static int edge=1;
  21.  
  22. #define quad(x) (x)*(x)
  23.  
  24. void Do_It(void)
  25. {
  26.   int i, j, k, l, posx, poss, index, abstand1, abstand2, x, y;
  27.   double r, g, b, h, s, u, v, su, mini, Re[81], Im[81];
  28.   unsigned char *srcR,*srcG, *srcB, *dstR, *dstG, *dstB;
  29.  
  30.   /* Zeiger auf Bilddaten holen */
  31.   srcR=source.redData;
  32.   srcG=source.greenData;
  33.   srcB=source.blueData;
  34.   dstR=desti.redData;
  35.   dstG=desti.greenData;
  36.   dstB=desti.blueData;
  37.  
  38.   /* gleiches maxval */
  39.   desti.maxval=source.maxval;
  40.   
  41.   /* Schleife ueber alle Punkte des Zielbildes */
  42.   /* => Randproblem unterdruecken */
  43.   for (i=edge; i<(n-edge); i++)
  44.     for (l=edge; l<(m-edge); l++)
  45.     {
  46.       index=l*n+i;   /* Index im Quellbild, Filtermittelpunkt */
  47.  
  48.       /* Filtermaske abarbeiten */
  49.       posx=0;
  50.       for (j=-edge; j<=edge; j++)
  51.         for (k=-edge; k<=edge; k++)
  52.         {
  53.           /* Punkt aus Originalbild kopieren */
  54.           poss=index+j*n+k;
  55.           r=(double) srcR[poss];
  56.           g=(double) srcG[poss];
  57.           b=(double) srcB[poss];
  58.  
  59.           /* RGB -> HSI: auf Singularitaeten pruefen */
  60.           if ((2.0*b-r-g!=0.0) && ((r-g)*(r-g)+r*g+2.0*b*(b-r-g)>0.0))
  61.           {
  62.             /* RGB -> HSI: Transformation */
  63.             u=2.0*b-r-g;
  64.             v=r-g;
  65.             h=atan2(v,u);
  66.             s=0.4082482905*sqrt(u*u+v*v);
  67.  
  68.             Re[posx]=s*cos(h);
  69.             Im[posx]=s*sin(h);
  70.           }
  71.           else
  72.           {
  73.             /* grosse Werte => Aussortieren bei Minimumsuche */
  74.             Re[posx]=1000.1;
  75.             Im[posx]=1000.1;
  76.           }
  77.           posx++;
  78.         }
  79.  
  80.       /* minimale Summe der Quadrate finden */
  81.       mini=6000000.0;
  82.       posx=0;
  83.       for (k=0; k<=4*edge*(edge+1); k++)
  84.       {
  85.         /* keine Singularitaetspunkte betrachten */
  86.         if (Re[k]<1000.0)
  87.         {
  88.           su=0.0;
  89.           for (j=0; j<=4*edge*(edge+1); j++)
  90.           {
  91.             /* keine Singularitaetspunkte betrachten */
  92.             if (Re[j]<1000.0) su+=quad(Re[k]-Re[j])+quad(Im[k]-Im[j]);
  93.           }
  94.           if (su<=mini)
  95.           {
  96.             if (su==mini)
  97.             {
  98.               x=posx/(2*edge+1)-edge;
  99.               y=posx%(2*edge+1)-edge;
  100.               poss=index+x*n+y;
  101.               abstand2=quad(srcR[poss]-srcR[index])+quad(srcG[poss]-srcG[index])+quad(srcB[poss]-srcB[index]);
  102.               if (abstand2<abstand1)
  103.               {
  104.                 abstand1=abstand2;
  105.                 posx=k;
  106.               }
  107.             }
  108.             else
  109.             {
  110.               mini=su;
  111.               posx=k;
  112.               x=posx/(2*edge+1)-edge;
  113.               y=posx%(2*edge+1)-edge;
  114.               poss=index+x*n+y;
  115.               abstand1=quad(srcR[poss]-srcR[index])+quad(srcG[poss]-srcG[index])+quad(srcB[poss]-srcB[index]);
  116.             }
  117.           }
  118.         }
  119.       }
  120.  
  121.       if (posx==0)
  122.       {
  123.         /* nur Singularitaetspunkte vorhanden => Originalpixel verwenden */
  124.         j=0;
  125.         k=0;
  126.       }
  127.       else
  128.       {
  129.         /* ausgewaehlten Pixel verwenden */
  130.         j=posx/(2*edge+1)-edge;
  131.         k=posx%(2*edge+1)-edge;
  132.       }
  133.  
  134.       /* Pixel ins Zielbild kopieren */
  135.       posx=(l-edge)*(n-2*edge)+i-edge;
  136.       poss=index+j*n+k;
  137.       dstR[posx]=srcR[poss];
  138.       dstG[posx]=srcG[poss];
  139.       dstB[posx]=srcB[poss];
  140.     }
  141. }
  142.  
  143. int main(int argc,char **argv)
  144. /* Hauptprogramm */
  145. {
  146.   int i;
  147.  
  148.   /* offizielle Begruessung */
  149.   PrintOpening(argc,argv);
  150.  
  151.   /* Uebergebene Parameter auswerten */
  152.   for (i=1; i<argc; i++)
  153.   {
  154.     if ((argv[i][0]=='-') && argv[i][1])
  155.     {
  156.       switch (argv[i][1])
  157.       {
  158.         case '3': edge=1;
  159.                       break;
  160.  
  161.         case '5': edge=2;
  162.                       break;
  163.  
  164.         case '7': edge=3;
  165.                       break;
  166.  
  167.         case '9': edge=4;
  168.                       break;
  169.  
  170.         case 'v': beVerbose=FALSE;
  171.                       break;
  172.  
  173.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  174.                      Hilfe();
  175.                      exit(-1);
  176.                      break;
  177.       }
  178.     }
  179.  
  180.     if (argv[i][0]=='+')
  181.     {
  182.       switch (argv[i][1])
  183.       {
  184.         case 'v': beVerbose=TRUE;
  185.                       break;
  186.  
  187.         default: PrintMessage("Unknown parameter: %s", argv[i]);
  188.                      Hilfe();
  189.                      exit(-1);
  190.                      break;
  191.       }
  192.     }
  193.   }
  194.  
  195.   /* Mindestzahl der Argumente pruefen */
  196.   if (argc<3)
  197.   {
  198.     PrintMessage("Wrong number of arguments !");
  199.     Hilfe();
  200.     exit(-1);
  201.   }
  202.  
  203.   /* Anzahl der Dateinamen überprüfen */
  204.   if (FilenameCount(argc, argv)!=2)
  205.   {
  206.     PrintMessage("Wrong number of file names !");
  207.     Hilfe();
  208.     exit(-1);
  209.   }
  210.  
  211.   if (ReadPPMFile(GetFilename(1,argc,argv),&source)==0)
  212.   {
  213.     m=source.height;
  214.     n=source.width;
  215.  
  216.     if ((m<=2*edge) || (n<=2*edge)) PrintMessage("The source picture is too small !!!");
  217.     else
  218.     {
  219.       if (CreatePPMArray(m-2*edge,n-2*edge,&desti)==0)
  220.       {
  221.         PrintMessage("Working ...");
  222.         Do_It();
  223.  
  224.         WritePPMFile(GetFilename(2,argc,argv),&desti);
  225.         FreePPMArray(&desti);
  226.       }
  227.     }
  228.  
  229.     FreePPMArray(&source);
  230.   }
  231.  
  232.   PrintClosing();
  233.   exit(0);
  234. }
  235.  
  236.